package pacBioSimple;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

import pacBiopackage.GetOpt;
//import pacBiopackage.PacBioErrorStatisticsContainer;
//import pacBiopackage.PacBioWriteStatistics;
import tools.kmer.KmerSet_binary;

public class PacBioKmerAlgoMain 
{
	private static final Logger log = Logger.getLogger( PacBioKmerAlgoMain.class.getName() ); 
	public static void main(String[] args) 
	{
		GetOpt go = new GetOpt(args, "o:k:a:h:n:l:e:jd");
		go.optErr = true;
		int ch = -1;
		
		// process options in command line arguments
		// Set default values
		boolean usagePrint = false;                 
		String filenameAlignment = "";   
		String filenameOutput="output.txt";
		String filenameKmerObject = "";
		boolean jelly =false;
		boolean debug_mode=true;
		int kmer_count_limit =175;
		int left_border=0;
		double entropy =1;
		while ((ch = go.getopt()) != GetOpt.optEOF) 
		{
		    if ((char)ch == 'h') {
		       usagePrint = true;
		   }
		    else if ((char)ch == 'a') {
		    	filenameAlignment = go.optArgGet();
		    }
		    else if((char)ch =='o')
		    {
		    	filenameOutput = go.optArgGet();
		    }
		    else if((char)ch =='n')
		    {
		    	kmer_count_limit=Integer.valueOf(go.optArgGet());
		    }
		    else if((char)ch =='k')
		    {
		    	filenameKmerObject=go.optArgGet();
		    }
		    else if((char)ch =='j')
		    {
		    	jelly=true;
		    }
		    else if((char)ch =='l')
		    {
		    	left_border=Integer.valueOf(go.optArgGet());
		    }
		    else if((char)ch =='e')
		    {
		    	entropy=Double.valueOf(go.optArgGet());
		    }
		    else if((char)ch =='D')
		    {
		    	debug_mode=true;;
		    }
		    else
		        System.exit(1);                     // undefined option
		}                                           // getopt() returns '?'
		
		if (usagePrint || filenameKmerObject.isEmpty() || filenameAlignment.isEmpty()) {
		    System.out.println("Usage: -a PacBio -k Kmer -n kmer_count_limit -l left -e entropy -j [ -o outputFile -h]"); //NOI18N
		    System.exit(0);
		}
		
		// @TODO check if files exist
	
		System.out.println("------------------------");
		System.out.println("Command line parameter settings:");
		System.out.println("-a " + filenameAlignment); //NOI18N
		System.out.println("-o " + filenameOutput); //NOI18N
		System.out.println("-n " + kmer_count_limit); //NOI18N
		System.out.println("-l " + left_border); //NOI18N
		System.out.println("-k " + filenameKmerObject); //NOI18N
		System.out.println("-e " + entropy); //NOI18N
		System.out.println("-j "+ jelly);		
		System.out.println("------------------------");
		
		//first we have to read the kmersFromthe file
		KmerSet_binary ks = null;
		System.out.println("creating kmerlist \n");
		KKmerList kmerVector = new KKmerList(10);
		System.out.println("creating kmerlist done \n");
		System.out.println(kmerVector.getKmerSize());
	
		if(debug_mode)
		{ 
			try
			{
				FileHandler fh = new FileHandler(filenameOutput+"_debug",true);
				log.addHandler(fh);
				log.setLevel(Level.ALL);
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
		//readingKmers
		ks=MyUtil.readKmers(filenameKmerObject, jelly, left_border, kmer_count_limit, ks);
		
		System.out.println("done reading kmers \n");

		PrintWriter pw=null;
		BufferedReader br = null;
		int counter=0;
		try
		{

			Writer fw = new FileWriter(filenameOutput);
			Writer bw = new BufferedWriter(fw);
			pw = new PrintWriter(bw);
			br = new BufferedReader(new FileReader(filenameAlignment));
			PrintWriter pw2 =new PrintWriter(new BufferedWriter(new FileWriter(filenameOutput+"_not_found")));
			PrintWriter pw3 = new PrintWriter(new BufferedWriter(new FileWriter(filenameOutput+"_seed_numbers")));
			PrintWriter pw4 = new PrintWriter(new BufferedWriter(new FileWriter(filenameOutput+"_linker_numbers")));
			PrintWriter pw5 = new PrintWriter(new BufferedWriter(new FileWriter(filenameOutput+"_contain_linker")));
			PrintWriter pw6 = new PrintWriter(new BufferedWriter(new FileWriter(filenameOutput+"_contain_different_seq")));
			//PacBioErrorStatisticsContainer stat = new PacBioErrorStatisticsContainer();
			CodingTable table = new CodingTable();
			PacBioMaster correctionKmer = new PacBioMaster(ks, table,kmer_count_limit,kmerVector,entropy);
			//PacBioCorrectionByKmers kmerCorrection = new PacBioCorrectionByKmers(ks,stat,freq_mode,freq_table);
			
			System.out.println("starting correction");
			while(br.ready())
			{
				//test if we are getting a copy of br or if its counting up
				PacBioReadContainer read = new PacBioReadIntoContainer().readIntoContainer(br);
				MyUtil.logging("HEADER "+read.getHeader());
				
					//log.log(Level.ALL, "HEADER "+read.getHeader());
			//System.out.println("HEADER "+read.getHeader());
//				System.out.println("Seq "+read.getOrginalSequence());
				
				//correctionKmer.run_single(read);
				correctionKmer.run_singleAlignmentThreaded(read);
				if(correctionKmer.isContamination())
				{
					
					for(int i=0; i < read.getContaminationBreakPoints().size();++i)
					{
						pw6.println(read.getHeader()+"_"+i);
						if(i==0)
						{
							pw6.println(read.getOrginalSequence().substring(0,read.getContaminationBreakPoints().get(i)));
						}
						else
						{
							pw6.println(read.getOrginalSequence().substring(read.getContaminationBreakPoints().get(i-1),read.getContaminationBreakPoints().get(i)));
						}
						
						if(i+1 == read.getContaminationBreakPoints().size()-1)
						{
							pw6.println(read.getHeader()+"_"+(i+1));
							pw6.println(read.getOrginalSequence().substring(read.getContaminationBreakPoints().get(i)));
						}
					}
				}
				else
				{
					pw3.println(correctionKmer.getSeeds().size());
					pw4.println(correctionKmer.getLinker_counter());
					//linker_counter+= correctionKmer.getLinker_counter();
					++counter;
					//pw.println(read.toString(true));
	//				System.out.println(read.toString());
					//log.fine(String.valueOf(counter)+"\n");
					MyUtil.logging("counter "+String.valueOf(counter)+"\n");
					System.out.println("counter "+String.valueOf(counter)+"\n");
					
					//write it that read to a file
	//				if(read.getCodingSeqeunce()!=null)
	//				{
	//					System.out.println(read.getCorrectedSequence());
	//				}
	//				else
	//				{
	//					System.out.println("no seed found ");
	//				}
					if(read.getCorrectedSequence()==null)
					{
						pw2.println(read.getHeader());
						pw2.println(read.getOrginalSequence());
					}
					else
					{
						if(correctionKmer.getLinker())
						{
							pw5.println(read.getHeader());
							pw5.println(read.getOrginalSequence());
							pw5.println(read.getCorrectedSequence());
							pw5.println(read.getCodingSeqeunce());
							pw5.println(read.getMarkedSequence());
						}
						else
						{
							pw.println(read.getHeader());
							pw.println(read.getOrginalSequence());
							pw.println(read.getCorrectedSequence());
							pw.println(read.getCodingSeqeunce());
							pw.println(read.getMarkedSequence());
						}
					}
	//				if(correctionKmer.getLinker_counter()>=6)
	//				{
	//					break;
	//				}
					pw.flush();
					pw2.flush();
					pw3.flush();
					pw4.flush();
					pw5.flush();
				}
			}
			pw.flush();
			pw.close();
			pw2.flush();
			pw2.close();
			pw3.flush();
			pw3.close();
			pw4.flush();
			pw4.close();
			pw5.flush();
			pw5.close();
			pw6.flush();
			pw6.close();
		}
		catch(Exception e)
		{
			e.printStackTrace();
			System.exit(1);
		}
		
	}
}
